/**
 * 核心模式提取器
 * 从完整知识库中提取高频通用模式，用于生成代码
 */

import * as fs from 'fs';
import * as path from 'path';

export interface CorePatterns {
    // size检查模式
    sizeCheckPatterns: {
        nullSizeCheck: string;      // if (data == nullptr || size < X)
        nullEmptyCheck: string;      // if (data == nullptr || size == 0)
        sizeofCheck: string;         // if (size < sizeof(Type))
    };
    
    // data使用模式
    dataUsagePatterns: {
        fuzzedDataProvider: {
            enabled: boolean;
            usage: number;  // 使用率 53%
            includes: string[];
            methods: string[];
        };
        messageParcel: {
            enabled: boolean;
            usage: number;  // 使用率 19%
            includes: string[];
            methods: string[];
        };
        memcpyS: {
            enabled: boolean;
            usage: number;  // 使用率 18%
            template: string;
        };
    };
    
    // BUILD.gn高频依赖
    buildGnPatterns: {
        essentialDeps: string[];     // 必需依赖 (>70%)
        commonDeps: string[];         // 常用依赖 (>30%)
        ipcDeps: string[];            // IPC场景依赖
        abilityDeps: string[];        // 能力框架依赖
        commonIncludes: string[];     // 常用include_dirs
    };
    
    // FuzzedDataProvider方法频率
    fdpMethods: {
        method: string;
        frequency: number;
        usage: string;
    }[];
}

export class CorePatternExtractor {
    
    /**
     * 从深度学习结果提取核心模式
     */
    static extractFromDeepLearning(): CorePatterns {
        const deepLearningPath = path.join(__dirname, 'fuzz-deep-analysis.json');
        
        if (!fs.existsSync(deepLearningPath)) {
            console.warn('[CorePatternExtractor] 深度学习文件不存在，使用默认模式');
            return this.getDefaultPatterns();
        }
        
        try {
            const data = JSON.parse(fs.readFileSync(deepLearningPath, 'utf-8'));
            
            return {
                sizeCheckPatterns: this.extractSizeCheckPatterns(data),
                dataUsagePatterns: this.extractDataUsagePatterns(data),
                buildGnPatterns: this.extractBuildGnPatterns(data),
                fdpMethods: this.extractFDPMethods(data)
            };
        } catch (error) {
            console.error('[CorePatternExtractor] 提取失败:', error);
            return this.getDefaultPatterns();
        }
    }
    
    /**
     * 提取size检查模式
     */
    private static extractSizeCheckPatterns(data: any) {
        const patterns = data.corePatterns?.sizeCheckPatterns || [];
        
        return {
            // 最常用: if (data == nullptr || size < sizeof(int32_t))
            nullSizeCheck: 'if (data == nullptr || size < sizeof(int32_t)) {\n        return 0;\n    }',
            
            // 简单场景: if (data == nullptr || size == 0)
            nullEmptyCheck: 'if (data == nullptr || size == 0) {\n        return 0;\n    }',
            
            // 结构体检查: if (size < sizeof(Type))
            sizeofCheck: 'if (size < sizeof(TYPE_PLACEHOLDER)) {\n        return 0;\n    }'
        };
    }
    
    /**
     * 提取data使用模式
     */
    private static extractDataUsagePatterns(data: any) {
        const usagePatterns = data.corePatterns?.dataUsagePatterns || [];
        
        // FuzzedDataProvider: 873次使用 (53%)
        const fdp = usagePatterns.find((p: any) => p.type === 'fuzzed_data_provider');
        
        // MessageParcel: 313次使用 (19%)
        const parcel = usagePatterns.find((p: any) => p.type === 'parcel_write_buffer');
        
        // memcpy_s: 290次使用 (18%)
        const memcpy = usagePatterns.find((p: any) => p.type === 'memcpy_s_from_data');
        
        return {
            fuzzedDataProvider: {
                enabled: true,
                usage: 0.53,
                includes: ['#include <fuzzer/FuzzedDataProvider.h>'],
                methods: [
                    'ConsumeRandomLengthString',
                    'ConsumeBool',
                    'ConsumeIntegral',
                    'ConsumeIntegralInRange',
                    'ConsumeRemainingBytesAsString'
                ]
            },
            messageParcel: {
                enabled: true,
                usage: 0.19,
                includes: ['#include "message_parcel.h"', '#include "message_option.h"'],
                methods: ['WriteBuffer', 'RewindRead', 'OnRemoteRequest']
            },
            memcpyS: {
                enabled: true,
                usage: 0.18,
                template: 'if (memcpy_s(buffer, bufferSize, data, size) != EOK) {\n    return 0;\n}'
            }
        };
    }
    
    /**
     * 提取BUILD.gn模式
     */
    private static extractBuildGnPatterns(data: any) {
        const buildGn = data.corePatterns?.buildGnPatterns || {};
        const highFreqDeps = buildGn.highFreqExternalDeps || [];
        
        // 提取不同频率的依赖
        const essential = highFreqDeps.filter((d: any) => d.frequency >= 0.7).map((d: any) => d.dep);
        const common = highFreqDeps.filter((d: any) => d.frequency >= 0.3 && d.frequency < 0.7).map((d: any) => d.dep);
        
        return {
            // 必需依赖 (70%+工程使用)
            essentialDeps: essential.length > 0 ? essential : [
                'c_utils:utils',
                'hilog:libhilog'
            ],
            
            // 常用依赖 (30-70%工程使用)
            commonDeps: common.length > 0 ? common : [
                'samgr:samgr_proxy',
                'ipc:ipc_core',
                'safwk:system_ability_fwk',
                'ability_base:want',
                'eventhandler:libeventhandler',
                'hitrace:hitrace_meter'
            ],
            
            // IPC场景依赖
            ipcDeps: [
                'ipc:ipc_core',
                'ipc:ipc_single',
                'samgr:samgr_proxy'
            ],
            
            // 能力框架依赖
            abilityDeps: [
                'ability_base:want',
                'ability_runtime:ability_manager',
                'ability_runtime:abilitykit_native'
            ],
            
            // 常用include_dirs
            commonIncludes: [
                '${subsystem_path}/interfaces/inner_api',
                '${subsystem_path}/services/include',
                '${subsystem_path}/common/include'
            ]
        };
    }
    
    /**
     * 提取FuzzedDataProvider方法使用频率
     */
    private static extractFDPMethods(data: any) {
        const fdpPatterns = data.corePatterns?.fuzzedDataProviderPatterns;
        
        if (!fdpPatterns || !fdpPatterns.commonMethods) {
            return this.getDefaultFDPMethods();
        }
        
        return fdpPatterns.commonMethods.map((m: any) => ({
            method: m.method,
            frequency: m.count,
            usage: this.getFDPMethodUsage(m.method)
        }));
    }
    
    /**
     * 获取FDP方法的使用说明
     */
    private static getFDPMethodUsage(method: string): string {
        const usageMap: Record<string, string> = {
            'ConsumeRandomLengthString': '生成随机长度字符串参数',
            'ConsumeBool': '生成bool类型参数',
            'ConsumeIntegral': '生成整数类型参数',
            'ConsumeIntegralInRange': '生成指定范围的整数参数',
            'ConsumeRemainingBytesAsString': '消费剩余所有数据为字符串',
            'ConsumeBytesAsString': '消费指定字节数为字符串',
            'ConsumeBytes': '消费指定字节数',
            'ConsumeFloatingPoint': '生成浮点数参数'
        };
        
        return usageMap[method] || '提取参数';
    }
    
    /**
     * 默认模式（如果深度学习文件不存在）
     */
    private static getDefaultPatterns(): CorePatterns {
        return {
            sizeCheckPatterns: {
                nullSizeCheck: 'if (data == nullptr || size < sizeof(int32_t)) {\n        return 0;\n    }',
                nullEmptyCheck: 'if (data == nullptr || size == 0) {\n        return 0;\n    }',
                sizeofCheck: 'if (size < sizeof(TYPE_PLACEHOLDER)) {\n        return 0;\n    }'
            },
            dataUsagePatterns: {
                fuzzedDataProvider: {
                    enabled: true,
                    usage: 0.53,
                    includes: ['#include <fuzzer/FuzzedDataProvider.h>'],
                    methods: ['ConsumeRandomLengthString', 'ConsumeBool', 'ConsumeIntegral']
                },
                messageParcel: {
                    enabled: true,
                    usage: 0.19,
                    includes: ['#include "message_parcel.h"'],
                    methods: ['WriteBuffer', 'OnRemoteRequest']
                },
                memcpyS: {
                    enabled: true,
                    usage: 0.18,
                    template: 'if (memcpy_s(buffer, bufferSize, data, size) != EOK) {\n    return 0;\n}'
                }
            },
            buildGnPatterns: {
                essentialDeps: ['c_utils:utils', 'hilog:libhilog'],
                commonDeps: ['samgr:samgr_proxy', 'ipc:ipc_core', 'safwk:system_ability_fwk'],
                ipcDeps: ['ipc:ipc_core', 'samgr:samgr_proxy'],
                abilityDeps: ['ability_base:want', 'ability_runtime:ability_manager'],
                commonIncludes: []
            },
            fdpMethods: this.getDefaultFDPMethods()
        };
    }
    
    /**
     * 默认FDP方法
     */
    private static getDefaultFDPMethods() {
        return [
            { method: 'ConsumeRandomLengthString', frequency: 2142, usage: '生成随机长度字符串参数' },
            { method: 'ConsumeBool', frequency: 364, usage: '生成bool类型参数' },
            { method: 'ConsumeIntegral', frequency: 200, usage: '生成整数类型参数' },
            { method: 'ConsumeIntegralInRange', frequency: 9, usage: '生成指定范围的整数参数' }
        ];
    }
    
    /**
     * 生成size检查代码
     */
    static generateSizeCheck(minSize: string = 'sizeof(int32_t)'): string {
        return `if (data == nullptr || size < ${minSize}) {
        return 0;
    }`;
    }
    
    /**
     * 生成FuzzedDataProvider代码
     */
    static generateFuzzedDataProviderCode(params: { name: string, type: string }[]): string {
        let code = '    FuzzedDataProvider fdp(data, size);\n\n';
        
        for (const param of params) {
            if (param.type.includes('string') || param.type.includes('String')) {
                code += `    std::string ${param.name} = fdp.ConsumeRandomLengthString(1024);\n`;
            } else if (param.type === 'bool') {
                code += `    bool ${param.name} = fdp.ConsumeBool();\n`;
            } else if (param.type.includes('int')) {
                code += `    ${param.type} ${param.name} = fdp.ConsumeIntegral<${param.type}>();\n`;
            } else {
                code += `    ${param.type} ${param.name} = fdp.ConsumeIntegral<${param.type}>();\n`;
            }
        }
        
        return code;
    }
    
    /**
     * 生成BUILD.gn external_deps
     */
    static generateExternalDeps(scenario: 'default' | 'ipc' | 'ability'): string[] {
        const patterns = this.extractFromDeepLearning();
        const deps = [...patterns.buildGnPatterns.essentialDeps];
        
        if (scenario === 'ipc') {
            deps.push(...patterns.buildGnPatterns.ipcDeps);
        } else if (scenario === 'ability') {
            deps.push(...patterns.buildGnPatterns.abilityDeps);
        }
        
        // 去重
        return Array.from(new Set(deps));
    }
}

